/**
 * 
 */
package com.netflexitysolutions.amazonws.sdb.orm.metadata;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang.StringUtils;

/**
 * @author netflexity
 *
 */
public class AbstractSimpleDBMetadata {
	
	private boolean lazy = true;
	private String name;
	private String className;
	private Class<?> javaClass;
	private Map<String, String> meta = new HashMap<String, String>();
	private ClassLoader classLoader = AbstractSimpleDBMetadata.class.getClassLoader();
	
	/**
	 * @return
	 */
	public String getClassName() {
		return className;
	}
    
	/**
	 * @param className
	 */
	public void setClassName(String className) {
		if(StringUtils.isBlank(className)){
			throw new MetadataException("'class' attribute must be supplied for " + this.getClass().getName());
		}

	    this.className = className;
		try {
			this.javaClass = (Class<?>)Class.forName(this.className, true, this.classLoader);
		} 
		catch (ClassNotFoundException e) {
			throw new MetadataException("Failed to find class '" + this.className + "' for " + this.getClass().getName());
		}
	}
    
	/**
	 * @return
	 */
	public String getName() {
		return name;
	}
    
	/**
	 * @param name
	 */
	public void setName(String name) {
		if(StringUtils.isBlank(name)){
			throw new MetadataException("'name' is a required unique attribute, which must be supplied for " + this.getClass().getName());
		}
		this.name = name;
	}
    
	/**
	 * @return
	 */
	public Map<String, String> getMeta() {
		return Collections.unmodifiableMap(meta);
	}
    
	/**
	 * @param key
	 * @return
	 */
	public String getMeta(String key) {
		return meta.get(key);
	}
    
	/**
	 * @param key
	 * @param defaultVal
	 * @return
	 */
	public String getMeta(String key, String defaultVal) {
        String val = meta.get(key);
		return StringUtils.isNotBlank(val) ? val : defaultVal;
	}
    
	/**
	 * @param key
	 * @param value
	 */
	public void addMeta(String key, String value) {
		if(StringUtils.isEmpty(key)){
			throw new MetadataException("'attribute' is a required attribute of <meta>, which must be supplied for " + this.getClass().getName());
		}
		this.meta.put(key, value);
	}
    
	/**
	 * @return
	 */
	public Class<?> getJavaClass() {
		return javaClass;
	}

    /**
	 * @return the lazy
	 */
	public boolean isLazy() {
		return lazy;
	}

	/**
	 * @param lazy the lazy to set
	 */
	public void setLazy(String lazy) {
		this.lazy = new Boolean(lazy).booleanValue();
	}

	/**
	 * @param lazy the lazy to set
	 */
	protected void setLazy(boolean lazy) {
		this.lazy = lazy;
	}

	/**
	 * @param meta the meta to set
	 */
	protected void setMeta(Map<String, String> meta) {
		this.meta = meta;
	}

	/* (non-Javadoc)
     * @see java.lang.Object#equals(java.lang.Object)
     */
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null || !obj.getClass().equals(getClass()))
            return false;
        return obj.toString().equals(toString());
    }

    /* (non-Javadoc)
     * @see java.lang.Object#hashCode()
     */
    @Override
    public int hashCode() {
        return toString().hashCode();
    }

    /* (non-Javadoc)
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        return getName() + ":" + getClassName();
    }
}
